package cc.rengu.igas.opms.core.service.trans.quickpay;

import cc.rengu.igas.opms.common.constant.OpmsParamConstant;
import cc.rengu.igas.opms.common.enums.RespCodeEnum;
import cc.rengu.igas.opms.common.util.QrCodeUtil;
import cc.rengu.igas.opms.core.service.base.ManageService;
import cc.rengu.igas.opms.facade.bean.StageInfo;
import cc.rengu.igas.opms.facade.request.StageProdInfoQueryRequest;
import cc.rengu.igas.opms.facade.response.StageProdInfoQueryResponse;
import cc.rengu.igas.share.core.model.MchntStageInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.dao.MchntOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.UserOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.MchntOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.UserOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.AcctTypeEnum;
import cc.rengu.oltp.service.common.enums.BaseProdEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.utility.util.AmountUtil;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.DateUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import com.alibaba.fastjson.JSON;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 分期产品查询服务
 *
 * @author keyi
 * @date 2020/3/21.
 */
public class StageProdInfoQueryService extends ManageService {

    @Override
    protected Object bizBeforeCust() throws Exception {
        StageProdInfoQueryRequest stageProdInfoQueryRequest = new StageProdInfoQueryRequest();
        ConvertUtil.convertOutput(stageProdInfoQueryRequest);
        return stageProdInfoQueryRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        BizResponse<StageProdInfoQueryResponse> bizResponse = new BizResponse<>();
        StageProdInfoQueryResponse stageProdInfoQueryResponse = new StageProdInfoQueryResponse();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);

        StageProdInfoQueryRequest stageProdInfoQueryRequest = (StageProdInfoQueryRequest) request;
        String instId = stageProdInfoQueryRequest.getHeader().getInstId();
        String mchntNo = stageProdInfoQueryRequest.getPlatMchntNo();
        String userOrdeId = stageProdInfoQueryRequest.getUserOrderId();

        //获取用户订单
        UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
        UserOrderInfo userOrderInfo = userOrderInfoMapper.selectUserOrderInfoByUserOrderId(instId, userOrdeId);
        if (userOrderInfo == null) {
            rglog.info("用户支付订单不存在");
            throw new BizException(RespCodeEnum.ORDER_NOEXIT.getRespCode(), RespCodeEnum.ORDER_NOEXIT.getRespDesc());
        }

        //扫银联码生成的订单有订单类型字段，作为付款方，没有商户订单，不做校验
        if (!QrCodeUtil.checkQrOrderType(userOrderInfo.getOrderType()) || StringUtil.isEmptyOrNull(userOrderInfo.getRemark2())) {
            MchntOrderInfoMapper mchntOrderInfoMapper = new MchntOrderInfoMapperImpl();
            List<MchntOrderInfo> mchntOrderInfos = mchntOrderInfoMapper.selectMchntOrderInfoBySysSeqNum(instId, userOrderInfo.getSysSeqNum());
            if (mchntOrderInfos == null || mchntOrderInfos.size() == 0) {
                rglog.info("商户订单表不存在该笔订单");
                bizResponse.setRespCode(RespCodeEnum.ORDER_NOEXIT.getRespCode());
                bizResponse.setRespDesc(RespCodeEnum.ORDER_NOEXIT.getRespDesc());
                return bizResponse;
            }
            if (mchntOrderInfos.size() > OpmsParamConstant.INT_ONE) {
                rglog.info("该订单为合并支付订单，不支持分期支付,返回空的分期列表。instId:<{}>,mchntOrderId:<{}>,orderSize:<{}>", instId, userOrdeId, mchntOrderInfos.size());
                bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
                bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
                return bizResponse;
            }
        }

        /*
         * 校验商户分期支付权限 T_B_MCHNT_AUTH_CTRL
         * 查询包括 分期支付(P01PM010)和手机银行扫码分期支付(P01PM012)
         */
        MchntService mchntService = new MchntServiceImpl();
        boolean checkResult = mchntService.checkMchntAuth(instId, mchntNo, null, "P01PM010", "00", AcctTypeEnum.ALL.getAcctType());
        if (!checkResult) {
            checkResult = mchntService.checkMchntAuth(instId, mchntNo, null, "P01PM012", "00", AcctTypeEnum.ALL.getAcctType());
            if (!checkResult) {
                rglog.info("该商户不支持手机银行扫码分期支付，mchntNo:<{}>", mchntNo);
                rglog.info("该商户在商户业务权限信息表中不存在或不支持该类型的分期支付");
                bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
                bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
                return bizResponse;
            }
        }
        //获取分期列表信息
        List<MchntStageInfo> mchntStageInfos = mchntService.getMchntStageInfo(instId, mchntNo);
        if (null == mchntStageInfos || mchntStageInfos.isEmpty()) {
            rglog.info("商户产品分期信息表查询结果为空。instId:<{}>,mchntNo:<{}>,baseProdCode:<{}>", instId, mchntNo, BaseProdEnum.STAGE_PAY.getProdCode());
            bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
            bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
            return bizResponse;
        }

        /*
         * 转换响应的分期产品列表
         * 分期产品记录状态不是Y时产品不可用
         * 不再分期产品的有效期间中产品不可用
         * 交易金额小于分期产品的最低限额时，该产品不可使用
         */
        String currentDate = DateUtil.getCurrentDate();
        ArrayList<StageInfo> stageInfoList = new ArrayList<>();
        StageInfo stageInfoRes = null;
        for (MchntStageInfo info : mchntStageInfos) {
            if (DateUtil.compareDate(currentDate, info.getFeeEffectiveDate()) < OpmsParamConstant.INT_ZERO || DateUtil.compareDate(currentDate, info.getFeeExpiryDate()) >= OpmsParamConstant.INT_ZERO) {
                rglog.info("商户分期产品费率未生效或已失效,feeEffectiveDate:<{}>,feeExpiryDate:<{}>", info.getFeeEffectiveDate(), info.getFeeExpiryDate());
                continue;
            }
            if (!StringUtil.isEmptyOrNull(userOrderInfo.getNeedPayAmt()) && AmountUtil.compare(info.getStageLimitAmt(), userOrderInfo.getNeedPayAmt()) == 1) {
                rglog.info("产品:<{}-{}>设置的分期最低限额:<{}>大于用户需要支付的金额:<{}>,当前分期产品不可用",
                        info.getProdStageCode(), info.getProdStageName(), info.getStageLimitAmt(), userOrderInfo.getNeedPayAmt());
                continue;
            }

            /*
             * 同一个分期产品使用同一条数据返回给前端，分期期数拼接，使用,分隔
             * 不同的分期产品则添加一条新的响应数据
             */
            boolean isContain = false;
            int index = 0;
            for (StageInfo stageInfo : stageInfoList) {
                if (info.getProdStageCode().equals(stageInfo.getStageProdCode())) {
                    stageInfo.setStageNum(stageInfo.getStageNum() + OpmsParamConstant.SEPARATORS_COMMA + info.getMchntStageNum());
                    stageInfo.setStageProdCode(info.getProdStageCode());
                    stageInfo.setStageProdDesc(" ");
                    isContain = true;
                    stageInfoRes = stageInfo;
                    break;
                }
                index++;
            }

            rglog.debug("当前分期产品集合中是否包含当前分期产品:<{}>", isContain);
            rglog.trace("当前分期产品集合:<{}>", JSON.toJSONString(stageInfoList));
            rglog.trace("当前分期产品下标:<{}>,当前分期产品:<{}>", index, JSON.toJSONString(stageInfoRes));
            if (!isContain) {
                stageInfoRes = new StageInfo();
                stageInfoRes.setStageNum(String.valueOf(info.getMchntStageNum()));
                stageInfoRes.setStageProdCode(info.getProdStageCode());
                stageInfoRes.setStageProdDesc(" ");
                stageInfoList.add(stageInfoRes);
            } else {
                stageInfoList.remove(index);
                stageInfoList.add(stageInfoRes);
            }
        }

        /*分期期数格式转换*/
        for (StageInfo stageInfo : stageInfoList) {
            String[] mchntStageNum = stageInfo.getStageNum().split(OpmsParamConstant.SEPARATORS_COMMA, -1);
            List<String> stageNumList = new ArrayList<>(Arrays.asList(mchntStageNum));
            stageInfo.setStageNumList(stageNumList);
        }

        //响应信息
        stageProdInfoQueryResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        stageProdInfoQueryResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        stageProdInfoQueryResponse.setStageInfoList(stageInfoList);
        bizResponse.setResult(stageProdInfoQueryResponse);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        StageProdInfoQueryResponse stageProdInfoQueryResponse = (StageProdInfoQueryResponse) bizResponse.getResult();
        ConvertUtil.convertInput(stageProdInfoQueryResponse);
    }
}
